package com.hgx.test;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.junit.Test;

import com.hgx.util.ProcessBaseUtil;

/**
 * 
 * 活动测试
 * 
 * @time 2017-2-16
 * 
 * @author Administrator
 * 
 */
public class CallAcitvitiTesst {

	ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("applicationContext.xml").buildProcessEngine();

	String processRecourcePath = "deployments/CallActivitiy.bpmn";
	String subProcessRecourcePath = "deployments/Check.bpmn";
	String processDefinitionKey = "callActivity";
	String subProcessDefinitionKey = "Check";
	String processAssignee = "张三";

	ProcessBaseUtil prob = new ProcessBaseUtil();

	/**
	 * 部署流程 主流程ID:97601 活动流程ID:97605
	 */
	@Test
	public void processDefinition() {
		// 部署主流程
		Deployment prod = prob.processDefinition("活动主流程", processRecourcePath);
		System.out.println("主流程ID:" + prod.getId());
		// 部署活动流程
		Deployment prodSub = prob.processDefinition("活动流程", subProcessRecourcePath);
		System.out.println("活动流程ID:" + prodSub.getId());
		// 主流程ID:117601
		// 活动流程ID:117605
	}

	/**
	 * 启动流程实例 流程实例ID:120101
	 * 
	 * ProcessDefinitionId:callActivity:4:117604
	 */
	@Test
	public void processStart() {

		// 启动流程实例
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("user", processAssignee);// 设置发起人

		List<String> candiateUserList = new ArrayList<String>();// 创建多个子流程用的集合
		candiateUserList.add("李五");
		variables.put("candiateUserList", candiateUserList);
		ProcessInstance startProcessInstance = prob.startProcessInstance(processDefinitionKey, variables);
		System.out.println("流程实例ID:" + startProcessInstance.getProcessInstanceId());

		List<ProcessInstance> list3 = processEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId(startProcessInstance.getProcessInstanceId()).list();
		
		if(1==list3.size()){
			System.out.println("ProcessDefinitionId:"+list3.get(0).getProcessDefinitionId());
		}

	}

	/**
	 * 查询流程实例
	 * 
	 */
	@Test
	public void findProcessInstance() {
		List<ProcessInstance> list = processEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId("112601").list();
		System.out.println(list.size());
		System.out.println(list.get(0).getProcessVariables());

	}

	/**
	 * 查询任务
	 */
	@Test
	public void findTask() {
		TaskService taskService = processEngine.getTaskService();
		List<Task> tasks = taskService.createTaskQuery()
		// 必须是根据sub process的definition key来查找task
				.processDefinitionKey(subProcessDefinitionKey).taskAssignee("李五")
				// 如果找到和这个process instance关联的sub process instance里的task
				// 就要用到在sub process instance里设置的变量
				// .processVariableValueEquals("user", processAssignee)
				// .taskDefinitionKey("usertask1")
				.list();
		System.out.println(tasks.size());
		// 处理任务
		// taskService.complete(tasks.get(0).getId());
	}

	/**
	 * 查询执行历史记录
	 * 
	 */
	@Test
	public void findHistory() {
		String processInstanceId = "112601";
		prob.queryHistoricActivitiInstance(processInstanceId);

	}

	@Test
	public void Test() {
		
		if(true){
			try {
				String imgPath = prob.dynamicProcessImg("120101", "e:/testActiviti/png/");
				System.out.println(imgPath);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return;
		}
		
		String processInstanceId = "120101";
		List<ProcessInstance> list3 = processEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId(processInstanceId).list();
		String processDefinitionId = list3.get(0).getProcessDefinitionId();
		System.out.println(processDefinitionId);
		List<Execution> list4 = processEngine.getRuntimeService().createExecutionQuery().processDefinitionId(processDefinitionId).list();
		for (Execution ex : list4) {
			System.out.println(ex.getId()+"\t"+ex.getActivityId());
		}
		if (true)
			return;

		RepositoryService repositoryService = processEngine.getRepositoryService();
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
		for (ProcessDefinition pd : list) {
			System.out.println(pd.getId() + "\t" + pd.getDeploymentId() + "\t");
		}
		RuntimeService runtimeService = processEngine.getRuntimeService();
		List<Execution> list2 = runtimeService.createExecutionQuery().list();
		for (Execution ex : list2) {
			System.out.println(ex.getId() + "\t" + ex.getProcessInstanceId());
		}
	}

	/**
	 * 获取流程图并 显示
	 * 
	 * @return
	 * @throws Exception
	 */

	@Test
	public void findProcessPic() {

		String processInstanceId = "callActivity:2:102604";
		// String procDefId = "97601";
		String procDefId = processInstanceId;
		try {
			RepositoryService repositoryService = processEngine.getRepositoryService();
			ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).singleResult();
			System.out.println(procDef);
			String diagramResourceName = procDef.getDiagramResourceName();
			InputStream imageStream = repositoryService.getResourceAsStream(procDef.getDeploymentId(), diagramResourceName);

			OutputStream os = new FileOutputStream("e:/testActiviti/png/test.png");

			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1) {
				os.write(buffer, 0, bytesRead);
			}
			os.close();
			imageStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取流程信息
	 * 
	 * @return
	 * @throws Exception
	 */

	@Test
	public void getProcessMap() {
		try {
			String procDefId = "callActivity:4:117604", executionId = "120107";
			System.out.println("获取流程定义信息:" + procDefId);
			System.out.println("获取流程实例信息:" + executionId);
			RepositoryService repositoryService = processEngine.getRepositoryService();
			ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).singleResult();
			System.out.println("查看流程定义名称:" + processDefinition.getName());
			ProcessDefinitionImpl pdImpl = (ProcessDefinitionImpl) processDefinition;
			String processDefinitionId = pdImpl.getId();
			System.out.println("流程标识 :" + processDefinitionId);
			ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
			ActivityImpl actImpl = null;

			RuntimeService runtimeService = processEngine.getRuntimeService();
			ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery().executionId(executionId).singleResult();
			// 执行实例

			String activitiId = execution.getActivityId();// 当前实例的执行到哪个节点
			System.out.println("当前执行节点id:" + activitiId);
			List<ActivityImpl> activitiList = def.getActivities();// 获得当前任务的所有节点
			System.out.println("当前任务的所有节点个数:" + activitiList.size());
			for (ActivityImpl activityImpl : activitiList) {
				String id = activityImpl.getId();
				if (id.equals(activitiId)) {// 获得执行到那个节点
					actImpl = activityImpl;
					break;
				}
			}
			System.out.println(actImpl.getX()+"\t"+actImpl.getY());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
